package bm.com.ai.server.LLModel.strategy;

import bm.com.ai.server.LLModel.config.GlobalAiConfig;
import bm.com.ai.server.dto.MessageRequest;
import bm.com.ai.server.dto.MessageResponse;
import bm.com.framework.common.exception.BmException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.util.UUID;

@Slf4j
public abstract class AbstractModelStrategy implements ModelStrategy {

    protected boolean initialized = false; //检查是否初始话

    @Resource
    private GlobalAiConfig globalAiConfig;

    @Override
    public MessageResponse process(MessageRequest request) {

        // 确保请求ID存在
        if (request.getRequestId() == null || request.getRequestId().isEmpty()) {
            request.setRequestId(UUID.randomUUID().toString());
        }

        // 设置请求的开始时间
        long startTime = System.currentTimeMillis();
        MessageResponse.MessageResponseBuilder responseBuilder = MessageResponse.builder()
                .requestId(request.getRequestId())
                .timestamp(LocalDateTime.now())
                .modelUsed(getModelType());

        try {

            // 初始化检查
            if (!initialized) {
                initialize();
            }

            // 日志记录 - 请求
            logRequest(request);

            log.info("Processing request " + request.getRequestId() + " with message " + request.getContent());

            // 执行具体处理（由子类实现）
            MessageResponse response = doProcess(request);

            System.out.println("MessageResponse :" + response);
            // 计算处理时间
            response.setProcessingTimeMs(System.currentTimeMillis() - startTime);

            // 日志记录 - 响应
            logResponse(response);

            return response;

        } catch (BmException e) {
            long processingTime = System.currentTimeMillis() - startTime;
            String errorMsg = "Error processing request " + request.getRequestId() + " with model " + getModelType() + ": " + e.getMessage();
            log.error(errorMsg, e.getMessage() + " -- " + e.getCause());

            return responseBuilder
                    .isSuccessful(false)
                    .errorMessage(errorMsg)
                    .processingTimeMs(processingTime)
                    .build();
        }
    }

    /**
     * 具体处理逻辑，由子类实现
     */
    protected abstract MessageResponse doProcess(MessageRequest request);

    /**
     * 日志记录 - 请求
     */
    protected void logRequest(MessageRequest request) {
        if (globalAiConfig.getLogging().isLogRequests()) {
            // 脱敏敏感数据
            String logMessage = "Processing request " + request.getRequestId() +
                    " with model " + getModelType() +
                    ", user: " + request.getUserId();

            log.info(logMessage);

            // 如果需要详细日志，可在此处添加
            if (log.isDebugEnabled()) {
                log.debug("Request content: {}", maskSensitiveData(request.getContent()));
            }
        }
    }

    /**
     * 记录响应日志
     */
    protected void logResponse(MessageResponse response) {
        if (globalAiConfig.getLogging().isLogResponses()) {
            String logMessage = "Processed request " + response.getRequestId() +
                    " with model " + response.getModelUsed() +
                    ", time: " + response.getProcessingTimeMs() + "ms" +
                    ", tokens: " + (response.getTokenStats() != null ? response.getTokenStats().getTotalTokens() : 0);

            log.info(logMessage);

            // 如果需要详细日志，可在此处添加
            if (log.isDebugEnabled() && response.getContent() != null) {
                log.debug("Response content: {}", maskSensitiveData(response.getContent()));
            }
        }
    }

    /**
     * 脱敏敏感数据 TODO: 根据实际需求实现,后期考虑数据持久化落库
     */
    protected String maskSensitiveData(String content) {
        if (content == null || !globalAiConfig.getLogging().isMaskSensitiveData()) {
            return content;
        }

        // 简单脱敏示例，可根据实际需求扩展
        String masked = content;
        masked = masked.replaceAll("(api_key|api_secret|token)[:=]\\s*[^\\s,]+", "$1=***");
        masked = masked.replaceAll("\\b(\\d{4})\\s*\\d{4}\\s*\\d{4}\\s*(\\d{4})\\b", "$1 **** **** $2");

        return masked;
    }
}
